# import datetime
# import json
# import os
# import re
# import time
# import uuid
#
# import pyautogui
# import requests
# from bs4 import BeautifulSoup
# import html2text
# from selenium.webdriver import ActionChains, Keys
# import undetected_chromedriver as uc
# from selenium.webdriver.common.by import By
# from selenium.webdriver.support.wait import WebDriverWait
#
# from domain.consts import express_shop_urls
# from eshoputils.browser_utils import getEleWait, getElesNoWait, getEleNoWait
# from eshoputils.mysql_util import MySqlUtil
# from graph.states import EshopAssistantState
#
#
# screen_width, screen_height = pyautogui.size()
# midx = screen_width // 2 + 150
# midy = screen_height // 2 + 200
#
# class ExpressShopSpider:
#     def __init__(self, state:EshopAssistantState, config, urls, work_dir):
#         self.urls = urls
#         self.state = state
#         self.config = config
#         self.work_dir = work_dir
#
#         chrome_options = uc.ChromeOptions()
#
#         #chrome_options = Options()
#         #chrome_options.add_experimental_option("detach", True)
#         #chrome_options.add_experimental_option('excludeSwitches',['enable-automation'])
#         #chrome_options.binary_location=r"C:\Program Files\Google\Chrome\Application\chrome.exe"
#         #chrome_options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36')
#         #无痕模式
#         #chrome_options.add_argument('--incognito')
#         prefs = {
#             'profile.default_content_setting_values.notifications':2,
#             #"profile.default_content_setting_values.cookies": 2,#禁用cookie
#             #"profile.default_content_setting_values.images": 2,#禁用图片
#             "profile.default_content_setting_values.plugins": 2,#禁用插件
#             "profile.default_content_setting_values.popups": 2,#禁止弹窗
#             "profile.default_content_setting_values.geolocation": 2,
#             #"profile.default_content_setting_values.automatic_downloads": 2,#禁止自动下载
#             "profile.default_content_setting_values.midi_sysex": 2,
#             "profile.default_content_setting_values.media_stream": 2,
#             "profile.default_content_setting_values.media_stream_mic": 2,
#             "profile.default_content_setting_values.media_stream_camera": 2,
#             "profile.default_content_setting_values.protocol_handlers": 2,
#             "profile.default_content_setting_values.mixed_script": 2,
#             "profile.default_content_setting_values.autoplay": 2,
#             "profile.default_content_setting_values.push_messaging": 2,
#             "profile.default_content_setting_values.ssl_cert_decisions": 2,
#             "profile.default_content_setting_values.metro_switch_to_desktop": 2,
#             "profile.default_content_setting_values.protected_media_identifier": 2,
#             "profile.default_content_setting_values.app_banner": 2,
#             "profile.default_content_setting_values.site_engagement": 2,
#             "profile.default_content_setting_values.durable_storage": 2,
#             "credentials_enable_service": False,  # 禁用密码管理
#             "profile.password_manager_enabled": False  # 禁用密码管理
#         }
#         # 禁用翻译提示
#         prefs["translate_whitelists"] = {}
#         chrome_options.add_experimental_option('prefs', prefs)
#         #chrome_options.add_argument(r'--user-data-dir=C:\Users\18222\AppData\Local\Google\Chrome\seleniumdata')
#         # # chrome_options.add_argument('--headless')
#         # # chrome_options.add_argument('--disable-gpu')
#         chrome_options.add_argument("--no-first-run")
#         chrome_options.add_argument("--no-default-browser-check")
#         chrome_options.add_argument("--allow-running-insecure-content")
#         #chrome_options.add_argument("--window-size=2576,1408")
#         # capabilities = DesiredCapabilities.CHROME.copy()
#         # capabilities["goog:chromeOptions"] = {"detach": True}
#
#         #chrome_service = webdriver.ChromeService(executable_path="../driver/chromedriver.exe", log_output=subprocess.STDOUT)
#         #self.browser = webdriver.Chrome(options=chrome_options,service=chrome_service)
#         # with open("../driver/steal1.js") as f:
#         #     self.js = f.read()
#         # self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
#         #     "source": self.js
#         # })
#
#         #self.browser = uc.Chrome(desired_capabilities=capabilities,user_data_dir=r"C:\Users\18222\AppData\Local\Google\Chrome\seleniumdata",debug=True,headless=True, use_subprocess=False, driver_executable_path="../driver/chromedriver.exe", browser_executable_path=r"C:\Program Files\Google\Chrome\Application\chrome.exe")
#         self.browser = uc.Chrome(options=chrome_options,user_data_dir=rf"C:\Users\18222\AppData\Local\Google\Chrome\seleniumdata\{self.work_dir[0]}",debug=True, headless=False, use_subprocess=True, driver_executable_path="driver/undetected_chromedriver.exe", browser_executable_path=r"C:\Program Files\Google\Chrome\Application\chrome.exe")
#         #self.browser = uc.Chrome(options=chrome_options,debug=True,headless=False, use_subprocess=False, driver_executable_path="driver/chromedriver.exe", browser_executable_path=r"C:\Program Files\Google\Chrome\Application\chrome.exe")
#         self.browser.maximize_window()
#         # self.browser.set_window_size(2576, 1408, self.browser.current_window_handle)
#         # self.browser.set_window_position(-6, 0)
#         self.waiter = WebDriverWait(self.browser, 1)
#
#     def __del__(self):
#         try:
#             self.browser.quit()
#         except:
#             pass
#
#     def update_state_info(self, info:str):
#         from graph.graph import EshopAssistantGraph
#         self.state["task_info"].append(info)
#         EshopAssistantGraph.graph.update_state(config=self.config, values = {"task_info":self.state["task_info"]})
#
#     def front_slide_check(self):
#         print(f'{self.work_dir[0]}:寻找滑动框')
#         self.update_state_info(f"{self.work_dir[0]}:寻找滑动框")
#         count = 0
#         slide_ele = getEleWait(self,'//*[@id="nc_1_n1z"]')
#         while slide_ele:
#             count += 1
#             print(f"{self.work_dir[0]}:有滑动框开始滑动")
#             self.update_state_info(f"{self.work_dir[0]}:有滑动框开始滑动")
#             #滑动
#             self.slide(slide_ele)
#             error_div = getEleWait(self,'//div[@id="`nc_1_refresh1`"]')
#             if error_div:
#                 print(f"{self.work_dir[0]}:滑动框出错，点击错误，准备重新滑动")
#                 ActionChains(self.browser).click(error_div).perform()
#             slide_ele = getEleWait(self,'//*[@id="nc_1_n1z"]')
#             if not slide_ele:
#                 print(f"{self.work_dir[0]}:滑块滑动成功")
#                 self.update_state_info(f"{self.work_dir[0]}:滑块滑动成功")
#             if count >= 3:
#                 break
#
#     def product_list_check(self):
#         print(f"{self.work_dir[0]}:找商品列表滑块")
#         self.update_state_info(f"{self.work_dir[0]}:寻找商品列表校验滑块")
#         frame =  getEleWait(self,'//*[@id="baxia-dialog-content"]')
#         if frame:
#             self.update_state_info(f"{self.work_dir[0]}:商品列表需要滑块校验")
#             print(f'{self.work_dir[0]}:商店列表访问需要滑块')
#             self.browser.switch_to.frame(frame)
#             self.front_slide_check()
#             self.browser.switch_to.default_content()
#         time.sleep(1)
#         self.browser.refresh()
#
#     def login_check(self):
#         print(f'{self.work_dir[0]}:找登陆框')
#         self.update_state_info(f"{self.work_dir[0]}:找登陆框")
#         login = getEleWait(self,'//input[@class="comet-input" and @label="Email"]')
#         count = 0
#         while login:
#             count += 1
#             self.update_state_info(f"{self.work_dir[0]}:需要登陆")
#             print(f'{self.work_dir[0]}:需要登陆')
#             #要登录
#             login.send_keys("zhupaizhiduozhi@gmail.com")
#             time.sleep(1)
#             div = getEleWait(self,'//*[@id="root"]/div/div/div[1]/div[3]/div[2]/div[2]/div/div/div/div/div/div/span[1]')
#             ActionChains(self.browser).click(div).perform()
#             button = getEleWait(self,'//*[@id="root"]/div/div/div[1]/div[3]/div[3]/button')
#             button.click()
#             passinput = getEleWait(self,'//*[@id="fm-login-password"]')
#             passinput.send_keys("Csvcn@112711")
#             snbutton = getEleWait(self,'//*[@id="root"]/div/div/div[3]/div[3]/button')
#             self.update_state_info(f"{self.work_dir[0]}:点击登陆按钮")
#             print(f'{self.work_dir[0]}:点击登陆按钮')
#             snbutton.click()
#             print(f'{self.work_dir[0]}:找登陆校验滑块')
#             self.update_state_info(f"{self.work_dir[0]}:登陆是否需要校验检查")
#             frame = getEleWait(self,'//*[@id="baxia-dialog-content"]')
#             if frame:
#                 self.update_state_info(f"{self.work_dir[0]}:登陆需要滑动校验")
#                 print(f"{self.work_dir[0]}:登陆需要校验滑块")
#                 x = frame.location['x']
#                 y = frame.location['y']
#                 pyautogui.moveTo(x, y, duration=0.01)
#                 pyautogui.moveTo(midx + 100, midy, duration=0.01)
#
#                 self.browser.switch_to.frame(frame)
#                 #登陆滑块校验
#                 self.front_slide_check()
#                 self.browser.switch_to.default_content()
#             time.sleep(3)
#             login = getEleWait(self,"//input[@class='comet-input' and @label='Email']")
#             if count >= 3:
#                 break
#
#     def enter_shop(self):
#         size = self.browser.get_window_size(self.browser.current_window_handle)
#         print(f"窗口大小{size}")
#         all_product_paths = []
#         #每个url代表一个店铺
#         for url in self.urls:
#             print(f"{self.work_dir[0]}:开始爬取url：{url[0]}")
#             self.update_state_info(f"{self.work_dir[0]}:开始爬取url：{url[0]}")
#             self.browser.get(url[0])
#             time.sleep(2)
#             #前端滑块
#             self.front_slide_check()
#             #登陆校验
#             self.login_check()
#             if url[1] == "product":
#                 #前端滑块
#                 print(f"{self.work_dir[0]}:此链接直接爬取固定商品详情")
#                 self.update_state_info(f"{self.work_dir[0]}:此链接直接爬取固定商品详情")
#                 self.update_state_info(f"{self.work_dir[0]}:校验此页面是否有滑块")
#                 self.front_slide_check()
#                 self.get_product_info(url, self.config['configurable']['thread_id'], all_product_paths, url[0], 0, None)
#             else:
#                 #商品列表滑块
#                 self.product_list_check()
#                 count = 0
#                 print(f'{self.work_dir[0]}:查看列表页是否出现')
#                 self.update_state_info(f"{self.work_dir[0]}:商品列表是否出现")
#                 flag = getEleWait(self,'//span[text()="Orders"]')
#                 flag2 = getEleWait(self, "//span[@class='topRefine2023--text--39fcGoQ' and text()='Best Match']")
#                 while not flag and not flag2:
#                     print(f'{self.work_dir[0]}:列表页没有展示，循环查看是否需要滑块校验')
#                     self.update_state_info(f'{self.work_dir[0]}:列表页没有展示，循环查看是否需要滑块校验')
#                     count += 1
#                     print(f'{self.work_dir[0]}:第{count}次校验是否有首页滑块')
#                     self.update_state_info(f'{self.work_dir[0]}:第{count}次校验是否有首页滑块')
#                     slide_ele = getEleWait(self,'//*[@id="nc_1_n1z"]')
#                     if slide_ele:
#                         self.update_state_info(f'{self.work_dir[0]}:第{count}次首页滑块滑动')
#                         #滑动
#                         self.slide(slide_ele)
#                     print(f'{self.work_dir[0]}:第{count}次校验是否有列表页滑块')
#                     self.update_state_info(f'{self.work_dir[0]}:第{count}次校验是否有列表页滑块')
#                     self.product_list_check()
#                     flag = getEleWait(self,'//span[text()="Orders"]')
#                     flag2 = getEleWait(self, "//span[@class='topRefine2023--text--39fcGoQ' and text()='Best Match']")
#                     if not flag and not flag2:
#                         print(f'{self.work_dir[0]}:第{count}次解决列表页滑块失败')
#                         self.update_state_info(f'{self.work_dir[0]}:第{count}次解决列表页滑块失败')
#                     if count >= 3:
#                         break
#                 if flag or flag2:
#                     print(f'{self.work_dir[0]}:列表加载成功开始爬取商品')
#                     self.update_state_info(f'{self.work_dir[0]}:列表加载成功开始爬取商品')
#                     galler_btn = getEleWait(self, "//span[text()='Gallery']")
#                     if galler_btn:
#                         ActionChains(self.browser).click(galler_btn).perform()
#                         time.sleep(1)
#                     #成功加载开始爬取
#                     all_product_paths += self.crawl(url)
#         #所有url爬完，关闭浏览器
#         print(f"{self.work_dir[0]}:所有url爬完关闭浏览器")
#         self.browser.quit()
#         return all_product_paths
#
#     def crawl(self, url):
#         task_id = self.config['configurable']['thread_id']
#         product_paths = []
#         print(f'{self.work_dir[0]}:进入爬取')
#         ActionChains(self.browser).scroll_by_amount(0, 1000).perform()
#         ActionChains(self.browser).scroll_by_amount(0, -1000).perform()
#         time.sleep(1)
#         if 'shop' == url[1]:
#             latest_products = self.browser.find_elements(By.XPATH, "//a[contains(@ae_button_type,'XRcmd-ItemClick')]")
#         else:
#             latest_products = self.browser.find_elements(By.XPATH, "//a[@class='multi--container--1UZxxHY cards--card--3PJxwBm search-card-item']")
#         self.update_state_info(f'{self.work_dir[0]}:第一页一共有{len(latest_products)}个产品')
#         print(f'{self.work_dir[0]}:第一页一共有{len(latest_products)}个产品')
#         home_handle = self.browser.current_window_handle
#
#         shop_name = None
#         if 'shop' == url[1]:
#             shop_name = getElesNoWait(self, "//a[contains(@data-href,'aliexpress.com/store')]/span")[0].text
#
#         #只取前10个商品
#         for index, latest_product in enumerate(latest_products[0:self.config["run_info"].num]):
#             print(f"{self.work_dir[0]}:开始获取第{index + 1}个商品")
#             self.update_state_info(f"{self.work_dir[0]}:开始获取第{index + 1}个商品")
#             time.sleep(0.5)
#             product_link = latest_product.get_attribute("href")
#             if self.config["run_info"].history_distinct:
#                 #历史去重
#                 res = MySqlUtil.execute_sql(f"select count(1) from spider_product_result where link = '{product_link}'")[0]
#                 if res[0] > 0:
#                     continue
#             try:
#                 latest_product.click()
#             except:
#                 print(f"{self.work_dir[0]}:第{index + 1}个商品链接点击出错")
#                 self.update_state_info(f"{self.work_dir[0]}:第{index + 1}个商品链接点击出错")
#                 continue
#             #self.waiter.until(expected_conditions.number_of_windows_to_be(2))
#             second_handle = None
#             for handle in self.browser.window_handles:
#                 if handle != home_handle:
#                     second_handle = handle
#                     break
#             self.browser.switch_to.window(second_handle)
#             time.sleep(2)
#             print(f"{self.work_dir[0]}:校验商品详情是否有滑动元素")
#             self.update_state_info(f'{self.work_dir[0]}:校验商品详情是否有滑动元素')
#             self.front_slide_check()
#             self.get_product_info(url, task_id, product_paths, product_link, index, shop_name)
#             self.update_state_info(f"{self.work_dir[0]}:第{index+1}个商品爬取完成")
#             #关闭标签回到商品列表页面
#             self.browser.close()
#             self.browser.switch_to.window(home_handle)
#         return product_paths
#
#     def get_product_info(self, url, task_id, product_paths, product_link, index, shop_name):
#         current_date = datetime.datetime.now().strftime("%Y-%m-%d")
#         ActionChains(self.browser).scroll_by_amount(0, 400).perform()
#         getEleWait(self,'//span[contains(text(),"View more")]')
#         more_btns = getElesNoWait(self,'//span[contains(text(),"View more")]')
#         try:
#             for more_brn in more_btns:
#                 ActionChains(self.browser).scroll_to_element(more_brn).perform()
#                 ActionChains(self.browser).click(more_brn).perform()
#                 time.sleep(0.5)
#         except:
#             print(f"{self.work_dir[0]}:more button 出错")
#             self.update_state_info(f"{self.work_dir[0]}:more button 没找到")
#         time.sleep(1)
#
#         beautifual = BeautifulSoup(self.browser.page_source, 'lxml')
#
#         if url[1] == 'shop':
#             type = "店铺"
#         elif url[1] == 'product':
#             type = '商品链接'
#         else:
#             type = '关键词'
#
#         dir_name = None
#         if type == '店铺':
#             dir_name = shop_name
#         elif type == '关键词':
#             dir_name = url[1]
#
#         if "aliexpress" in url[0]:
#             platform_type = "express（速卖通平台）"
#         else:
#             platform_type = "shopee（虾皮平台）"
#
#         if dir_name:
#             #创建目录
#             product_dir = f'download/{current_date}/{task_id}/{platform_type}/{type}/{dir_name}/{index+1}_{uuid.uuid4().hex}'
#         else:
#             product_dir = f'download/{current_date}/{task_id}/{platform_type}/{type}/所有商品/{uuid.uuid4().hex}'
#
#         product_paths.append(str(product_dir))
#         self.mkdir(product_dir)
#         picdir = f'{product_dir}/oripic'
#         self.mkdir(picdir)
#
#         #获取信息
#         #listing
#         listing_ele = getEleNoWait(self,'//h1[@data-pl="product-title"]')
#         listing = self.get_ele_text(listing_ele)
#         print(f"{self.work_dir[0]}:第{index+1}个商品listing：{listing}")
#         self.update_state_info(f"{self.work_dir[0]}:第{index+1}个商品listing：{listing}")
#
#         #price
#         price = self.get_price()
#         print(f"{self.work_dir[0]}:第{index+1}个商品price：{price}")
#         self.update_state_info(f"{self.work_dir[0]}:第{index+1}个商品price：{price}")
#
#         #imgs
#         res = re.findall("imagePathList\":\[[\d\w\-\.:\/\",]*\]",self.browser.page_source)
#         if res:
#             good_img_urls = json.loads(res[0][15:])
#             for ix, good_img_url in enumerate(good_img_urls):
#                 gr = requests.get(good_img_url, stream=True)
#                 with open(f"{picdir}/{ix+1}_{uuid.uuid4().hex}.png", "wb") as w:
#                     w.write(gr.content)
#         else:
#             print(f'{self.work_dir[0]}:第{index+1}个商品没有图片：网页源码：{self.browser.page_source}')
#         sku_img_eles = getElesNoWait(self, "//div[contains(@class, 'sku-item--image')]/img")
#
#         #sku_img
#         for ixs, sku in enumerate(sku_img_eles):
#             try:
#                 img_url = sku.get_attribute("src")
#                 big_img_url = re.sub(r'[\d]{1,4}x[\d]{1,4}', "800x800",img_url)
#                 gr = requests.get(big_img_url, stream=True)
#                 with open(f"{picdir}/{ix+ixs+1}_{uuid.uuid4().hex}.png", "wb") as w:
#                     w.write(gr.content)
#             except:
#                 print(f"{self.work_dir[0]}:点击sku出错")
#                 self.update_state_info(f"{self.work_dir[0]}:点击sku出错")
#
#
#         #爬specifications
#         specification_divs = getElesNoWait(self,"//div[contains(@class,'specification--prop')]")
#         specifications_info = {}
#         for div in specification_divs:
#             title = div.find_element(By.XPATH, './div[contains(@class,"specification--title")]').find_element(By.XPATH, './span').text
#             desc = div.find_element(By.XPATH, './div[contains(@class,"specification--desc")]').find_element(By.XPATH, './span').text
#             if title and desc:
#                 specifications_info[title] = desc
#
#         #爬description
#         description_wrapper = beautifual.find(name='div', id='nav-description')
#         plain_html = str(description_wrapper)
#
#         #原html
#         with open(f'{product_dir}/des_plain_html.txt','w', encoding='utf-8') as file:
#             file.write(plain_html)
#
#         #转md
#         md = html2text.html2text(plain_html)
#         with open(f'{product_dir}/des_md.md','w', encoding='utf-8') as file:
#             file.write(md)
#
#         #转纯文本
#         plain_text = html2text.HTML2Text().handle(plain_html)
#         with open(f'{product_dir}/des_plain_text.txt','w', encoding='utf-8') as file:
#             file.write(plain_text)
#
#         #组装信息
#         product_info = {
#             'link':product_link,
#             'price':price,
#             'listing':listing,
#             'specifications':specifications_info
#         }
#
#         with open(f'{product_dir}/product_info.json', 'w') as file:
#             json.dump(product_info, file, indent=4)
#
#
#     def get_price(self):
#         price_path = [
#             '//*[@id="root"]/div/div[1]/div/div[1]/div[1]/div[2]/div[1]/div/span[1]',
#             '//*[@id="root"]/div/div[3]/div/div[1]/div[1]/div[2]/div[1]/div[2]/span[1]',
#             "//span[contains(@class, 'price--currentPriceText')]",
#             "//span[contains(@class,'price--originalText')]"
#         ]
#         paths = '|'.join(price_path)
#         price_ele = getEleNoWait(self,paths)
#         price = self.get_ele_text(price_ele)
#         if not price:
#             last_prict_ele = getElesNoWait(self,"//div[@class='es--wrap--vZDQqfj notranslate']")
#             if last_prict_ele:
#                 if isinstance(last_prict_ele, list):
#                     last_prict_ele = last_prict_ele[0]
#                 child_elements = last_prict_ele.find_elements(By.XPATH, './*')
#                 for child in child_elements:
#                     price += self.get_ele_text(child)
#         return price
#
#
#     def get_ele_text(self, ele):
#         if ele:
#             return ele.text
#         return ""
#
#     def mkdir(self, path):
#         folder = os.path.exists(path)
#         if not folder:
#             os.makedirs(path)
#
#     # def getEleWait(self, xpath):
#     #     ele = None
#     #     try:
#     #         ele = self.waiter.until(expected_conditions.presence_of_element_located(
#     #             (By.XPATH, xpath)
#     #         ))
#     #     except Exception as e:
#     #         print("没有找到元素")
#     #     return ele
#     #
#     # def getEleNoWait(self, xpath):
#     #     try:
#     #         return self.browser.find_element(By.XPATH, xpath)
#     #     except:
#     #         print(f"没有找到元素：{xpath}")
#     #         return None
#     #
#     # def getElesNoWait(self, xpath):
#     #     try:
#     #         return self.browser.find_elements(By.XPATH, xpath)
#     #     except:
#     #         print(f'没有找到元素{xpath}')
#     #         return None
#
#
#     def slide(self, button):
#         """
#         滑动变阻器！！
#         :return:
#         """
#         try:
#             pyautogui.moveTo(midx + 100, midy, duration=0.01)
#             ActionChains(self.browser).click_and_hold(button).perform()
#             for x in [1]*5:
#                 bt = getElesNoWait(self, '//*[@id="nc_1_n1z"]')
#                 if not bt:
#                     break
#                 pyautogui.move(1, 0, duration=0.01)
#                 ActionChains(self.browser).move_by_offset(xoffset=x*100, yoffset=0).perform()
#                 time.sleep(0.05)
#         except Exception as e:
#             pass
#
#
#     def slidebak2(self, button):
#         """
#         滑动变阻器！！
#         :return:
#         """
#         print(f"滑块位置{button.location['x'], button.location['y']}")
#         print(f"鼠标位置{midx+100},{midy}")
#         try:
#             # pyautogui.moveTo(midx + 100, midy, duration=0.01)
#             ActionChains(self.browser).click_and_hold(button).perform()
#             time.sleep(0.5)
#             ActionChains(self.browser).move_to_element_with_offset(button,100,100).perform()
#             time.sleep(0.5)
#             ActionChains(self.browser).move_to_element_with_offset(button,100,100).perform()
#             time.sleep(0.5)
#             ActionChains(self.browser).move_to_element_with_offset(button,100,100).perform()
#             for x in range(1,5):
#                 # pyautogui.move(1, 0, duration=0.01)
#                 ActionChains(self.browser).move_by_offset(xoffset=x*100, yoffset=0).perform()
#                 time.sleep(0.05)
#         except Exception as e:
#             pass
#
#     def slidebak3(self, button):
#         """
#        拖动滑块
#        :param slider: 滑块
#        :param tracks: 轨迹
#        :return:
#        """
#         # 模拟滑动滑块
#         tracks = self.get_tracks(300)
#         action = ActionChains(self.browser)
#         action.click_and_hold(button).perform()
#         # action.reset_actions()   # 清除之前的action
#         for i in tracks:
#             action.move_by_offset(xoffset=i, yoffset=0).perform()
#         time.sleep(0.5)
#         action.release().perform()
#
#     def get_tracks(self, distance):
#         """
#         根据偏移量获取移动轨迹
#         :param distance:偏移量
#         :return:移动轨迹
#         """
#         # 移动轨迹
#         tracks = []
#         # 当前位移
#         current = 0
#         # 减速阈值
#         mid = distance * 4 / 5
#         # 计算间隔
#         t = 0.2
#         # 初速度
#         v = 0
#         while current < distance:
#             if current < mid:
#                 # 加速度为正10.值大则速度快
#                 a = 10
#             else:
#                 # 加速度为负3
#                 a = -3
#             # 初速度v0
#             v0 = v
#             # 当前速度
#             v = v0 + a * t
#             # 移动距离
#             move = v0 * t + 1 / 2 * a * t * t
#             # 当前位移
#             current += move
#             # 加入轨迹
#             tracks.append(round(move))
#         return tracks
#
#     def slidebak(self, button):
#         """
#         滑动变阻器！！
#         :return:
#         """
#         try:
#             pyautogui.moveTo(midx + 100, midy, duration=0.01)
#             ActionChains(self.browser).click_and_hold(button).perform()
#             for x in [1]*5:
#                 ActionChains(self.browser).move_by_offset(xoffset=x*100, yoffset=0).perform()
#                 time.sleep(0.5)
#                 pyautogui.move(1, 0, duration=0.01)
#         except Exception as e:
#             pass
